/*
 * Copyright (c) 2010 Andy Aspell-Clark
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

package uk.co.droidinactu.sony.prst1.home;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import uk.co.droidinactu.sony.prst1.home.data.Book;
import uk.co.droidinactu.sony.prst1.home.data.SonyDataModel;
import android.app.Application;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.Log;

/**
 * 
 * @author andy
 * 
 */
public final class SonyPrsT1HomeApplication extends Application {

    public static String LOG_TAG = "SonyPrsT1HomeApplication:";

    public String calibreMetadataFilename = "metadata.calibre";
    public Book contextMenuSelectedBook;

    private SonyDataModel dataMdl;

    public final DecimalFormat decFmt = new DecimalFormat("#0.00");
    public final DecimalFormat gbp = new DecimalFormat("£#0.00");

    public int nbrGridCols = 4;
    public int nbrGridRows = 10;
    public final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    public ArrayList<ArrayList<String>> tagLevels = new ArrayList<ArrayList<String>>();

    /*
     * Create a temporary file to see whether a volume is really writeable. It's
     * important not to put it in the root directory which may have a limit on
     * the number of files.
     */
    protected boolean checkFsWritable() {
        final String directoryName = Environment.getExternalStorageDirectory().toString() + "/DCIM";
        final File directory = new File(directoryName);
        if (!directory.isDirectory()) {
            if (!directory.mkdirs()) {
                return false;
            }
        }
        final File f = new File(directoryName, ".probe");
        try {
            // Remove stale file if any
            if (f.exists()) {
                f.delete();
            }
            if (!f.createNewFile()) {
                return false;
            }
            f.delete();
            return true;
        } catch (final IOException ex) {
            return false;
        }
    }

    protected Drawable getAppImage(final String packageName) {
        try {
            return this.getPackageManager().getApplicationIcon(packageName);
        } catch (final NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getApplicationAuthor() {
        return this.getString(R.string.app_author);
    }

    public String getApplicationAuthorEmail() {
        return this.getString(R.string.about_email);
    }

    public String getApplicationAuthorWebsite() {
        return this.getString(R.string.about_website_url);
    }

    public String getApplicationDescription() {
        return this.getString(R.string.app_explanation);
    }

    public Bitmap getApplicationImage() {
        return BitmapFactory.decodeResource(this.getResources(), R.drawable.ic_launcher);
    }

    public String getApplicationName() {
        return this.getString(R.string.app_name);
    }

    public String getApplicationVersion() {
        return this.getAppVersion("uk.co.droidinactu.sony.prst1.home");
    }

    public String getAppSdCardPathDir() {
        final File extDir = Environment.getExternalStorageDirectory();
        return extDir.getPath() + File.separator + this.getApplicationName() + File.separator;
    }

    protected String getAppVersion(final String packageName) {
        String verName = "unknown";
        try {
            final PackageInfo pInfo = this.getPackageManager()
                    .getPackageInfo(packageName, PackageManager.GET_META_DATA);
            verName = pInfo.versionName;
        } catch (final NameNotFoundException e) {
            e.printStackTrace();
        }
        return verName;
    }

    public final String getCalibreFilename() {
        return this.getSdCardDir() + File.separator + this.calibreMetadataFilename;
    }

    public SonyDataModel getDataModel() {
        return this.dataMdl;
    }

    public String getLogTag() {
        return SonyPrsT1HomeApplication.LOG_TAG;
    }

    public int getNbrCpuCores() {
        return Runtime.getRuntime().availableProcessors();
    }

    public String getPayPalDonateName() {
        return "InLibrisLibertas";
    }

    public final String getSdCardDir() {
        final File extDir = Environment.getExternalStorageDirectory();
        return extDir.getPath() + File.separator;
    }

    public boolean hasStorage() {
        return this.hasStorage(true);
    }

    public boolean hasStorage(final boolean requireWriteAccess) {
        final String state = Environment.getExternalStorageState();
        Log.v(this.getLogTag(), "storage state is " + state);

        if (Environment.MEDIA_MOUNTED.equals(state)) {
            if (requireWriteAccess) {
                final boolean writable = this.checkFsWritable();
                Log.v(this.getLogTag(), "storage writable is " + writable);
                return writable;
            } else {
                return true;
            }
        } else if (!requireWriteAccess && Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            return true;
        }
        return false;
    }

    public boolean isIntentAvailable(final String action) {
        final PackageManager packageManager = this.getPackageManager();
        final Intent intent = new Intent(action);
        final List resolveInfo = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        if (resolveInfo.size() > 0) {
            return true;
        }
        return false;
    }

    public Boolean isSdAvailable() {
        boolean mExternalStorageAvailable = false;
        boolean mExternalStorageWriteable = false;

        final String state = Environment.getExternalStorageState();

        if (Environment.MEDIA_MOUNTED.equals(state)) {
            // We can read and write the media
            mExternalStorageAvailable = mExternalStorageWriteable = true;
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            // We can only read the media
            mExternalStorageAvailable = true;
            mExternalStorageWriteable = false;
        } else {
            // Something else is wrong. It may be one of many other states, but
            // all we need
            // to know is we can neither read nor write
            mExternalStorageAvailable = mExternalStorageWriteable = false;
        }
        return mExternalStorageAvailable;
    }

    public void setDataModel(final SonyDataModel dataMdl) {
        this.dataMdl = dataMdl;
    }
}
